# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
ICOIcon.py
By: Denver Coneybeare <denver@sleepydragon.org>
Oct 28, 2012
"""

from __future__ import print_function
from __future__ import unicode_literals

from Error import Error
from Icon import Icon

from winapi_constants import IMAGE_ICON
from winapi_constants import LR_DEFAULTSIZE
from winapi_constants import LR_LOADFROMFILE

class ICOIcon(Icon):
    """
    An implementation of Icon whereby the icon is loaded from an ICO file.
    """

    def __init__(self, path, winapi=None):
        """
        Initializes a new instance of this class.
        *path* must be a Unicode string whose value is the path of the ICO file
        to load.
        *winapi* must be the winapi module or a compatible object and will be
        used to perform the low-level operations required by this class; it is
        recommended to simply specify None (the default) in order to use the
        winapi module directly; this argument is primarily intended for use
        during unit testing of this class, and should not normally be explicitly
        specified.
        Raises TypeError if the given path is not a Unicode string.
        Raises winnotify.Error if loading the icon from the ICO file with the
        given path fails.
        """
        if not isinstance(path, unicode):
            raise TypeError("invalid type for path: {} (expected unicode)"
                .format(type(path)))

        if winapi is None:
            import winapi as winapi_module
            winapi = winapi_module
        self.winapi = winapi

        handle = winapi.LoadImage(
            hinst=0,
            lpszName=path,
            uType=IMAGE_ICON,
            cxDesired=0,
            cyDesired=0,
            fuLoad=LR_DEFAULTSIZE|LR_LOADFROMFILE,
        )
        if handle == 0:
            (errno, message) = self.winapi.get_last_error()
            raise Error("unable to load icon from ICO file: {} "
                "(LoadImage failed: {} ({}))".format(path, errno, message))

        Icon.__init__(self, handle)


    def __del__(self):
        """
        Calls DestroyIcon on self.handle.
        """
        try:
            handle = self.handle
        except AttributeError:
            pass # __init__() did not complete; nothing to do
        else:
            try:
                winapi = self.winapi
            except AttributeError:
                pass # DestroyIcon function not available; nothing we can do
            else:
                if handle is not None:
                    self.handle = None
                    winapi.DestroyIcon(handle)
